<?php

namespace Lib\Model\Datasource;

use Lib\Model\Datasource,
    Lib\Util\Util,
    Lib\Exception\DatasourceException,
    mysqli;

class Mysql extends Datasource {

    private $connection;
    private $connected = false;
    private $error;

    private $lastInsertId;

    public function connect() {
        $cfg = $this->config;
        $this->connection = new mysqli($cfg->host, $cfg->username, $cfg->password, $cfg->database);

        $this->execute("SET NAMES {$cfg->encoding}");
        $this->connected = true;
    }

    public function close() {
        $this->connection->close();
        $this->connected = false;
    }

    public function query($options) {
        if (is_array($options)) {
            $sql = $this->options2sql($options);
        } else {
            $sql = $options;
        }

        $result = $this->connection->query($sql);
        if ($result !== false) {
            if ($result !== true) {
                $ret = array();
                while ($row = $result->fetch_assoc()) {
                    $ret[] = $row;
                }
                return $ret;
            } else {
                return true;
            }
        } else {
            throw new DatasourceException($this->connection->error);
        }
    }

    public function execute($sql) {
        $return = false;
        if ($result = $this->connection->query($sql)) {
            $return = $this->connection->affected_rows>0 ? true : false;
            $this->error = $return ? null : $this->connection->error;
            $this->lastInsertId = $this->connection->insert_id;
        } else {
            $this->error = $this->connection->error;
        }

        return $return;
    }

    public function lastError() {
        return $this->error;
    }

    public function options2sql($options) {
        // SELECT
        $fields = empty($options['fields']) ? '*' : implode(',', $options['fields']);
        $select = "SELECT $fields";

        // FROM
        $from  = 'FROM ' . $this->model->table . ' ' . $this->model->name;

        // WHERE
        $where = 'WHERE 1';
        if (! empty($options['conditions'])) {
            foreach ($options['conditions'] as $field => $pattern) {
                $where .= ' AND ' . $this->escape($field) . '=\'' . $this->escape($pattern) . '\'';
            }
        }

        // GROUP BY
        $group = '';

        // ORDER BY
        $order = '';
        if (! empty($options['order'])) {
            $order = 'ORDER BY ' . $options['order'];
        } else if (! empty($this->model->order)) {
            $order = 'ORDER BY ' . $this->model->order;
        }


        // LIMIT
        $limit = '';
        if ((int)$options['limit'] > 0) {
            $limit = (int)$options['limit'];
            $page  = (int)$options['page']; $page = $page>0 ? $page : 1;
            $start = ($page - 1) * $limit;
            $limit = 'LIMIT ' . $start . ', ' . $limit;
        }

        return "$select $from $where $group $order $limit";
    }

    public function escape($string) {
        if (! $this->connected) $this->connect();
        return $this->connection->real_escape_string($string);
    }

    public function lastInsertId() {
        return $this->lastInsertId;
    }

}